#include "messageParsing.h"

char* announce_getListenPort(char* string)
{
  char* response;
  char* tempStr = strdup(string);
  char* junk1 __attribute__((unused)) = strtok(tempStr, " "); // "listen"
  char* strPort = strtok(NULL," "); // $PORT
  response = strdup(strPort);
  free(tempStr);
  return response;
}

char* announce_getSeedList(char* string)
{
  char* response;
  char* tempStr = strdup(string);
  DBG("tempStr = %s\n", tempStr);
  char* junk1 __attribute__((unused)) = strtok(tempStr, "["); // "announce ..."
  DBG("junk1 = %s\n", junk1);
  char* strSeedList = strtok(NULL,"]");
  DBG("strSeedList = %s\n", strSeedList);
  if (strstr(strSeedList,"leech") != NULL)
    {
      free(tempStr);
      return NULL;
    }
  //  printf("SeedList = %s\n", strSeedList);
  response = strdup(strSeedList);
  free(tempStr);
  return response;
}

char* announce_getLeechList(char* string)
{
  char* response;
  char* tempStr = strdup(string);
  char* junk1 __attribute__((unused)) = strtok(tempStr, "]"); // "announce ... [seedList] ..."
  char* junk2 __attribute__((unused)) = strtok(NULL,"["); // leech
  char* strLeechList = strtok(NULL,"]");
  if (strLeechList == NULL)
    {
      free(tempStr);
      return NULL;
    }
  //  printf("LeechList = %s\n", strLeechList);
  response = strdup(strLeechList);
  free(tempStr);
  return response;
}

char* look_getCriterionList(char* string)
{
  DBG("Parsing look data : %s\n" , string);
  char* response;
  char* tempStr = strdup(string);
  //  char* junk1 __attribute__((unused)) = strtok(tempStr, "["); // look
  
  char* strCriterionList = strtok(tempStr,"[]");
  DBG("Criterion list = %s\n", strCriterionList);
  response = strdup(strCriterionList);
  free(tempStr);
  return response;
}

char* getfile_getKey(char* string)
{
  // Useless function, just for compatibility
  /*
  DBG("Parsing getKey data : <%s>\n", string); 
  char* response;
  char* tempStr = strdup(string);
  char* junk1 __attribute__((unused)) = strtok(tempStr," ");
  char* strKey = strtok(NULL," ");
  assert(strKey != NULL);
  response = strdup(strKey);
  free(tempStr); */
  return string;
}

char* update_getSeedList(char* string)
{
  char* response;
  char* tempStr = strdup(string);
  char* junk1 __attribute__((unused)) = strtok(tempStr, "["); // update
  char* strSeedList = strtok(NULL,"]");
  //  printf("SeedList = %s\n", strSeedList);
  if (strstr(strSeedList,"leech") != NULL)
    {
      free(tempStr);
      return NULL;
    }
  response = strdup(strSeedList);
  free(tempStr);
  return response;
}

char* update_getLeechList(char* string)
{
  char* response;
  char* tempStr = strdup(string);
  char* junk1 __attribute__((unused)) = strtok(tempStr, "]"); // "update [ ... ]"
  char* junk2 __attribute__((unused)) = strtok(NULL,"["); // leech
  char* strLeechList = strtok(NULL,"]");
  if (strLeechList == NULL)
    {
      free(tempStr); 
      return NULL;
    }
  //  printf("LeechList = %s\n", strLeechList);
  response = strdup(strLeechList);
  free(tempStr);
  return response;
}

hashtable* announce_parseSeedList(char* string)
{
  DBG("parsing seedList => %s\n", string);
  hashtable* fileList = createTable(256);
  char* tempStr = strdup(string);
  char* buffer;
  char* strFileName, *strFileLength, *strPieceSize, *strKey;
  int step = 0;
  buffer = strtok(tempStr, " ");
  while(buffer != NULL)
    {
      switch(step)
	{
	case 0: // FILENAME
	  {
	    strFileName = strdup(buffer);
	  } break;
	case 1: // FILE_LENGTH
	  {
	    strFileLength = strdup(buffer);
	  } break;
	case 2: // PIECE_SIZE
	  {
	    strPieceSize = strdup(buffer);
	  } break;
	case 3: // KEY
	  {
	    strKey = strdup(buffer);
	    addData(strKey,
		    (void*) createFile(strFileName,
				       atoi(strFileLength), 
				       atoi(strPieceSize)),
		    fileList);
	    free(strFileName);
	    free(strFileLength);
	    free(strPieceSize);
	    free(strKey);
	  } break;
	}
      buffer = strtok(NULL, " ");
      step = (step + 1) % 4;
    }
  //  assert(step == 0 && "Malformed seedList string");
  free(tempStr);
  if (step != 0)
    {
      WG("Malformed seedlist, step was = %d\n", step);
      return NULL;
    }
  return fileList;
}

list* announce_parseLeechList(char* string)
{
  if (string == NULL)
    {
      WG("%s","null string in parseLeechList\n");
      return NULL;
    }
  else
    {
      char* tempStr = strdup(string);
      char* buffer;
      list* l = NULL;
      buffer = strtok(tempStr, " ");
      while (buffer != NULL)
	{
	  addElementToList((void*)buffer, l);
	  buffer = strtok(NULL, " ");
	}
      free(tempStr);
      return l;
    }
}

criterion* parseCriterion(char* string)
{
  DBG("Parsing single criterion <%s>\n", string);
  criterionOperator op;
  criterionField fi;
  char delim = ' ';
  char* opPosition;
  if  (strchr(string, '=') != NULL)
    {
      opPosition = strchr(string,'=');
      op = CRIT_EQ;
      delim = '=';
    }
  else if (strchr(string, '>') != NULL)
    {
      opPosition = strchr(string,'>');
      op = CRIT_G;
      delim = '>';
    }
  else if (strchr(string, '<') != NULL)
    {
      opPosition = strchr(string,'<');
      op = CRIT_L;
      delim = '<';
    }
  else
    {
      assert(0 && "DAFUCK !");
    }
  DBG("delimiter = %c\n", delim);
  char* tmpStr = strdup(string);
  char* field = strtok(tmpStr, &delim);
  DBG("field = %s\n", field);
  char* data = strtok(NULL, "\"");
  DBG("data = %s\n", data);
  if (strstr(field,"filename") != NULL)
    {
      fi = CRIT_FILENAME;
    }
  else if (strstr(field,"filesize") != NULL)
    {
      fi = CRIT_FILESIZE;
    }
  else
    {
      WG("%s","Inccorrect criterion ( unknown field )\n");
      free(tmpStr);
      return NULL;
    }
  criterion* c = createCriterion(op, fi, data);
  DBG("Criterion %s %c %s\n", field, delim, data);
  free(tmpStr);
  return c;
}

list* parseCriterionList(char* string)
{
  DBG("trying to parse < %s > \n", string);
  list* l = NULL;
  char* tempStr = strdup(string);
  char* buffer = strtok(tempStr," ");
  while(buffer != NULL)
    {
      DBG("adding %s to the list\n", buffer);
      l = addElementToList(((void*)strdup(buffer)), l);
      buffer = strtok(NULL," ");
    } 
  free(tempStr);
  DBG("%s","Dumping criterion list\n");
  dumpList(l);
  return l;
}

char* fileListToString(list* l)
{
  assert(l != NULL);
  char* str = malloc(sizeof(char) * 4096);
  while(l!=NULL)
    {
      char tmp[512];
      file* f = (file*)l->data;
      sprintf(tmp, "%s %d %d %s", f->fileName, f->length, f->pieceSize, 
	      getKey(f, globalTrackerData->fileList));
      strncat(str,tmp,strlen(tmp));
      l = l->next;
      if (l)
	strcat(str," ");
    }
  return str;
}

char* peerListToString(list* l)
{
  assert(l != NULL);
  char* str = malloc(sizeof(char) * 4096);
  while(l!=NULL)
    {
      char tmp[512];
      peer* p = (peer*)l->data;
      sprintf(tmp, "%s:%s", p->ip, p->port);
      strncat(str,tmp,strlen(tmp));
      l = l->next;
      if (l)
	strcat(str," ");
    }
  return str;
}


list* update_parseLeechSeedList(char* seeders, char* leechers)
{
  DBG("parseSeedLeechList : seddStr = <%s> leechStr = <%s>\n", seeders, leechers);
  char* tempStr1 = strdup(seeders);
  char* tempStr2 = strdup(leechers);
  list* l = NULL;
  char* buffer = NULL;
  if (tempStr1 != NULL)
    {
      DBG("Adding seeders %s\n", tempStr1);
      buffer = strtok(tempStr1, " ");
      // ajout des seeders
      while(buffer != NULL)
	{
	  DBG("adding %s\n", buffer);
	  l = addElementToList(strdup(buffer), l);
	  buffer = strtok(NULL," ");
	}
    }
  if (tempStr2 != NULL)
    {
      DBG("%s","Adding leechers\n");
      buffer = strtok(tempStr2, " ");
      // ajout des leechers
      while(buffer != NULL)
	{
	  DBG("adding %s\n", buffer);
	  l = addElementToList(strdup(buffer), l);
	  buffer = strtok(NULL," ");
	}
    }
  free(tempStr1);
  free(tempStr2);
  return l;
}
